/*
 * $Id: $
 */
package org.rcgwt.client.ui.grid.internal;

import org.rcgwt.client.ui.grid.event.ModelElementChangedEvent;
import org.rcgwt.client.ui.grid.internal.model.IGridEventManager;
import org.rcgwt.client.ui.grid.internal.model.IGridModel;
import org.rcgwt.client.ui.grid.internal.model.IElementModelDelta;
import org.rcgwt.client.ui.grid.model.IGridWidget;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.IncrementalCommand;

/**
 * 
 * @author Olivier Oeuillot (latest modification by $Author: $)
 * @version $Revision: $ $Date: $
 */
public class GridEventManagerImpl implements IGridEventManager,
        IncrementalCommand {
    private final IGridWidget gridWidget;

    private IElementModelDelta<IGridModel> gridModelDelta;

    private int refCount;

    private int defferedCommand = 0;

    public GridEventManagerImpl(IGridWidget gridWidget) {
        this.gridWidget = gridWidget;
    }

    public void enter() {
        if (refCount > 0) {
            refCount++;
            return;
        }

        // On peut rerentrer car l'evenement n'est pas encore consommé !
        if (gridModelDelta == null) {
            gridModelDelta = new DefaultModelElementDelta<IGridModel>(
                    gridWidget.getGridModel());
        }

        refCount = 1;
    }

    public void exit() {
        refCount--;
        if (refCount > 0) {
            return;
        }

        if (defferedCommand == 0) {
           // Log.info("Add event command");

            DeferredCommand.addCommand(this);
        }

        defferedCommand++;
    }

    public IElementModelDelta<IGridModel> getGridModelDelta() {
        if (gridModelDelta == null) {
            throw new IllegalStateException("Not into an event managed scope");
        }
        return gridModelDelta;
    }

    @Override
    public boolean execute() {
       // Log.info("Execute event defferedCommand='" + defferedCommand+ "' refCount='" + refCount + "'.");

        defferedCommand = 0;

        if (refCount > 0) {
            return true;
        }

        try {
            fireEvent();

        } catch (Throwable th) {
            Log.error("Fire event throws exception", th);
        }

        return false;
    }

    protected void fireEvent() {
        IElementModelDelta<IGridModel> old = gridModelDelta;
        gridModelDelta = null;

        //Log.info("Fire event:\n" + old.toString(""));

        ModelElementChangedEvent.fire(gridWidget, old);
    }

}
